import numpy as np
from sympy import *

# 查表得出各个情况的Xk和Ak
Xk = [
    [0.0000000],
    [-0.5773503, 0.5773503],
    [-0.7745967, 0.0000000, 0.7745967],
    [-0.8611363, -0.3399810, 0.3399810, 0.8611363],
    [-0.9061798, -0.5384693, 0.0000000, 0.5384693, 0.9061798],
    [-0.9324695, -0.6612094, -0.2386192, 0.2386192, 0.6612094, 0.9324695]
]

Ak = [
    [2.0000000],
    [1.0000000, 1.0000000],
    [0.5555556, 0.8888889, 0.5555556],
    [0.3478548, 0.6521452, 0.6521452, 0.3478548],
    [0.2369269, 0.4786287, 0.5688889, 0.4786287, 0.2369269],
    [0.1713245, 0.3607616, 0.4679139, 0.4679139, 0.3607616, 0.1713245]
]


def t(begin, end, point):
    """
    计算
    :param begin:
    :param end:
    :param point:
    :return:
    """
    # 根据传入参数确定是哪种高斯公式，选择对应的Xk和Ak值
    xs = np.array(Xk[point - 1]) * (end - begin) / 2 + (begin + end) / 2
    temp = Ak[point - 1]
    T = 0
    for i in range(point):
        T += (Y.subs(x, xs[i]) * temp[i])
    return T * (end - begin) / 2


def loss(begin=-1, end=1, point=3):
    """
    :param begin:
    :param end:
    :return:
    """
    T = sum([t(xl[i], xl[i + 1], point) for i in range(n)])
    # 求和
    I = integrate(Y, (x, begin, end))
    print('误差为--%.18f' % (I - T).evalf())
    print("结果为----", T)


if __name__ == '__main__':
    # 复合的三点高斯公式计算,五点高斯公式不需要计算
    # 定义变量5
    x = symbols('x')
    # 三点高斯公式
    point = 3
    n = 4
    xl = np.linspace(-1, 1, n + 1)

    # 如果高斯公式的区间不为-1,1。需要进行变换的为[-1,1]
    Y = 1 / (x + 2)
    loss(point=point)
